package com.microservice.salmon.fastdfs.controller;

import com.microservice.salmon.fastdfs.client.FastDFSClient;
import com.salmon.common.ApiResponse;
import com.salmon.common.utils.MimeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  文件通用上传下载
 * </p>
 *
 * @author 王洪庆 2019-01-07 09:34
 */
@RestController
@Api(tags = "文件通用上传下载", description = "文件通用上传下载模块")
@RequestMapping("/file")
public class FastDFSController {

    @Autowired
    private FastDFSClient fastDFSClient;

    @PostMapping("/upload")
    @ApiOperation(value="文件上传，返回文件上传后的URL地址", notes = "文件上传")
    @ApiImplicitParam(name = "file",value = "上传文件input name属性为file")
    public ApiResponse upload(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        String url = fastDFSClient.uploadFile(multipartFile);
        return ApiResponse.ofSuccess(url);
    }

    @PostMapping(value = "/batch/upload")
    @ApiOperation("文件批量上传,返回上传后的URL地址")
    @ApiImplicitParam(name = "file", value = "批量上传文件，input name的值为 file")
    public ApiResponse batchUpload(@RequestParam("file") List<MultipartFile> multipartFileList) throws IOException {
        List<Map<String, String>> urls = new ArrayList<>();
        for (MultipartFile multipartFile: multipartFileList) {
            String uri = fastDFSClient.uploadFile(multipartFile);
            Map<String, String> result = new HashMap<>();
            result.put("uri", uri);
            urls.add(result);
        }
        return ApiResponse.ofSuccess(urls);
    }

    @DeleteMapping("/delete/")
    @ApiOperation("文件删除，返回删除成功与否的状态")
    @ApiImplicitParam(name = "path", value = "要删除文件的路径")
    public ApiResponse deleteFile(@RequestParam("path") String fileUrl) {
        fastDFSClient.deleteFile(fileUrl);
        return ApiResponse.ofSuccess();
    }

    @DeleteMapping(value = "/batch/delete", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation("文件批量删除,返回删除成功与否的状态,接收JSON [{url: xxx}]")
    @ApiImplicitParam(paramType = "body", dataType = "Array", name = "fileUrlList", value = "要删除文件的url地址 [{url: xxx}]")
    public ApiResponse batchDeleteFile(@RequestBody List<Map<String,String>> fileUrlList) {
        for (Map<String, String> fileMap : fileUrlList) {
            fastDFSClient.deleteFile(fileMap.get("url"));
        }
        return ApiResponse.ofSuccess();
    }

    @PostMapping(value = "/upload/base64", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiOperation("上传Base64格式的数据,接收JSON格式的数据[{data:xxx，ext: png, thumb: false}]")
    @ApiImplicitParam(paramType = "body", dataType = "Array", name = "data", value = "JSON格式的数据[{data:xxx，ext: png, thumb: true|false}]", required = true)
    public ApiResponse uploadBase64(@RequestBody List<Map<String,String>> data) throws Exception {
        List<Map<String, String>> urls = new ArrayList<>();
        for (Map<String, String> fileMap : data) {
            String base64  = fileMap.get("data");
            byte [] bytes = Base64Utils.decodeFromString(base64);
            String uri = fastDFSClient.uploadFile(bytes, fileMap.get("ext"),
                    fileMap.get("thumb") == null ? false : Boolean.valueOf(fileMap.get("thumb")));
            Map<String, String> result = new HashMap<>();
            result.put("uri", uri);
            urls.add(result);
        }
        return ApiResponse.ofSuccess(urls);
    }

    @GetMapping("/download")
    @ApiOperation(value="下载文件", notes = "下载文件")
    @ApiImplicitParam(value = "文件路径", name = "path")
    public ResponseEntity<Object> getFile(@RequestParam("path") String fileUrl) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        Resource resource = new InputStreamResource(fastDFSClient.downloadFile(fileUrl));
        String fileName = UUID.randomUUID().toString().replace("-", "") + "." + FilenameUtils.getExtension(fileUrl);
        headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, StandardCharsets.UTF_8.displayName()));
        String mediaType = MimeUtils.getFileMimeType(fileName); // 根据文件名获取mediaType
        return ResponseEntity.ok().headers(headers).contentType(MediaType.parseMediaType(mediaType)).body(resource);
    }
}
